package com.hmall.common.interceptor;

import com.hmall.common.utils.UserContext;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.springframework.amqp.core.Message;
import org.springframework.aop.framework.AopProxyUtils;
import org.springframework.aop.framework.ProxyFactory;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.stereotype.Component;

import java.util.Map;

/**
 * MQ消费者拦截器，用于在消息消费前自动设置用户上下文
 */
@Component
public class MQConsumerInterceptor implements MethodInterceptor, BeanPostProcessor {
    
    @Override
    public Object invoke(MethodInvocation invocation) throws Throwable {
        Object[] arguments = invocation.getArguments();
        
        // 尝试从参数中获取Message对象
        Message message = null;
        for (Object arg : arguments) {
            if (arg instanceof Message) {
                message = (Message) arg;
                break;
            }
        }
        
        if (message != null) {
            // 从消息头中获取用户信息
            Map<String, Object> headers = message.getMessageProperties().getHeaders();
            if (headers != null && headers.containsKey("user-info")) {
                Object userIdObj = headers.get("user-info");
                if (userIdObj != null) {
                    try {
                        Long userId = Long.valueOf(userIdObj.toString());
                        UserContext.setUser(userId);
                    } catch (NumberFormatException e) {
                        // 忽略无效的用户ID
                    }
                }
            }
        }
        
        try {
            // 执行实际的消息处理逻辑
            return invocation.proceed();
        } finally {
            // 清理用户上下文
            UserContext.removeUser();
        }
    }

    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        return bean;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        Class<?> targetClass = AopProxyUtils.ultimateTargetClass(bean);
        
        // 检查是否有@RabbitListener注解的方法
        if (hasRabbitListenerMethod(targetClass)) {
            // 为该bean创建代理
            ProxyFactory proxyFactory = new ProxyFactory(bean);
            proxyFactory.setProxyTargetClass(true); // 使用CGLIB代理
            proxyFactory.addAdvice(this);
            return proxyFactory.getProxy();
        }
        
        return bean;
    }
    
    private boolean hasRabbitListenerMethod(Class<?> clazz) {
        // 检查类中是否有@RabbitListener注解的方法
        for (java.lang.reflect.Method method : clazz.getDeclaredMethods()) {
            if (method.isAnnotationPresent(org.springframework.amqp.rabbit.annotation.RabbitListener.class) ||
                method.isAnnotationPresent(org.springframework.amqp.rabbit.annotation.RabbitListeners.class)) {
                return true;
            }
        }
        // 也要检查父类
        Class<?> superClass = clazz.getSuperclass();
        if (superClass != null && superClass != Object.class) {
            return hasRabbitListenerMethod(superClass);
        }
        return false;
    }
}